package org.gl.training.gwt.client.view;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.gl.training.gwt.client.SessionManager;
import org.gl.training.gwt.client.service.TaskService;
import org.gl.training.gwt.client.service.TaskServiceAsync;
import org.gl.training.gwt.client.utils.MyAsyncCallback;
import org.gl.training.gwt.shared.model.DailyPlanVO;
import org.gl.training.gwt.shared.model.TaskVO;
import org.gl.training.gwt.shared.model.UserVO;
import org.gl.training.gwt.shared.utils.RecordUtils;

import com.google.gwt.core.client.GWT;
import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.types.Cursor;
import com.smartgwt.client.types.ImageStyle;
import com.smartgwt.client.types.SelectionAppearance;
import com.smartgwt.client.types.SelectionStyle;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.Button;
import com.smartgwt.client.widgets.Img;
import com.smartgwt.client.widgets.Label;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.fields.DateItem;
import com.smartgwt.client.widgets.form.fields.events.ChangedEvent;
import com.smartgwt.client.widgets.form.fields.events.ChangedHandler;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.ListGridRecord;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.HStack;
import com.smartgwt.client.widgets.layout.LayoutSpacer;
import com.smartgwt.client.widgets.layout.VLayout;

public class DailyPlanView extends HLayout {

	private ListGrid userGrid;

	private DateItem dateItem;

	private TaskServiceAsync taskService = GWT.create(TaskService.class);

	private Integer userId;

	private DailyPlanVO dailyPlanVO;

	private Label dailyPlanOwnerLabel;

	public DailyPlanView(Integer userId) {
		this.userId = userId;
		setWidth100();
		setHeight100();

		VLayout mainLayout = new VLayout();
		mainLayout.setBorder("1px solid #629efa");
		mainLayout.setWidth(700);
		mainLayout.setHeight100();

		setMembers(new LayoutSpacer(), mainLayout, new LayoutSpacer());

		mainLayout.addMember(new HeaderView());

		VLayout body = new VLayout(10);
		body.setMargin(10);
		body.setWidth100();
		body.setHeight100();

		mainLayout.addMember(body);
		mainLayout.addMember(new FooterView());

		// Init body
		UserVO currentUserVO = SessionManager.getCurrentUserVO();
		Label labelUser = new Label(currentUserVO.getFullName());
		labelUser.setStyleName("header-text");
		labelUser.setWrap(false);

		Img infoImg = new Img("info.jpg");
		infoImg.setImageWidth(24);
		infoImg.setImageHeight(24);
		infoImg.setImageType(ImageStyle.NORMAL);
		infoImg.setCursor(Cursor.HAND);
		infoImg.addClickHandler(new InfoHandler());

		dailyPlanOwnerLabel = new Label();
		dailyPlanOwnerLabel.setHeight("20px");
		dailyPlanOwnerLabel.setStyleName("header-text");
		dailyPlanOwnerLabel.setWrap(false);

		DynamicForm form = new DynamicForm();

		dateItem = new DateItem();
		dateItem.setTitle("Choose plan date");
		dateItem.addChangedHandler(new CalendarChangedHandler());
		// dateItem.setAttribute("useTextField", true);
		form.setFields(dateItem);

		HStack currentUserLayout = new HStack(5);
		currentUserLayout.setWidth100();
		currentUserLayout.setHeight(24);
		currentUserLayout.addMember(labelUser);
		currentUserLayout.addMember(infoImg);

		body.addMember(currentUserLayout);
		if (!securityCheck()) {
			body.addMember(dailyPlanOwnerLabel);
		}
		body.addMember(form);

		userGrid = new ListGrid();
		userGrid.setWidth100();
		userGrid.setHeight100();
		userGrid.setShowAllRecords(true);
		userGrid.setSelectionAppearance(SelectionAppearance.CHECKBOX);
		userGrid.setSelectionType(SelectionStyle.SIMPLE);

		ListGridField eventField = new ListGridField("event", "Event");
		ListGridField timeField = new ListGridField("time", "Time");
		ListGridField estimateDurationField = new ListGridField(
				"estimateDuration", "Estimate duration");
		ListGridField actualDurationField = new ListGridField("actualDuration",
				"Actual duration");
		ListGridField commentsField = new ListGridField("comments", "Comments");

		userGrid.setFields(new ListGridField[] { eventField, timeField,
				estimateDurationField, actualDurationField, commentsField });

		body.addMember(userGrid);

		HLayout buttonsLayout = new HLayout();
		buttonsLayout.setMembersMargin(10);
		buttonsLayout.setWidth100();
		buttonsLayout.setHeight(24);

		Button createButton = new Button("Create");
		createButton.addClickHandler(new CreateHandler());
		createButton.setVisible(securityCheck());

		Button editButton = new Button("Edit");
		editButton.addClickHandler(new EditHandler());
		editButton.setVisible(securityCheck());

		Button deleteButton = new Button("Delete");
		deleteButton.addClickHandler(new DeleteHandler());
		deleteButton.setVisible(securityCheck());

		Button backButton = new Button("Back");
		backButton.addClickHandler(new BackHandler());
		backButton.setVisible(!securityCheck());

		buttonsLayout.addMember(createButton);
		buttonsLayout.addMember(editButton);
		buttonsLayout.addMember(deleteButton);
		buttonsLayout.addMember(backButton);
		buttonsLayout.setAlign(Alignment.RIGHT);

		body.addMember(buttonsLayout);

		loadDailyPlan();
	}

	protected void loadDailyPlan() {
		Date date = dateItem.getValueAsDate();
		taskService.getDailyPlan(userId, date, new LoadDailyPlanCallback());
	}

	protected boolean securityCheck() {
		return userId == SessionManager.getCurrentUserVO().getId();
	}

	public void setDailyPlanOwnerText(String dailyPlanOwner) {
		dailyPlanOwnerLabel.setContents(dailyPlanOwner);
	}

	private class LoadDailyPlanCallback extends MyAsyncCallback<DailyPlanVO> {

		@Override
		public void onSuccess(DailyPlanVO result) {
			dailyPlanVO = result;
			setTaskGridData(dailyPlanVO.getTaskVOList());
		}
	}

	private class CalendarChangedHandler implements ChangedHandler {

		@Override
		public void onChanged(ChangedEvent event) {
			loadDailyPlan();
		}
	}

	protected void setTaskGridData(List<TaskVO> taskVOList) {
		List<ListGridRecord> taskRecordList = RecordUtils
				.getTaskGridRecords(taskVOList);
		ListGridRecord[] taskRecords = taskRecordList
				.toArray(new ListGridRecord[taskRecordList.size()]);
		userGrid.setData(taskRecords);
	}

	protected List<Integer> getSelectedIds() {
		ListGridRecord[] selectedRecords = userGrid.getSelectedRecords();

		List<Integer> idList = new ArrayList<Integer>();

		for (ListGridRecord selectedRecord : selectedRecords) {
			Integer id = selectedRecord.getAttributeAsInt("id");
			idList.add(id);
		}
		return idList;
	}

	protected List<TaskVO> getSelectedTasks() {
		ListGridRecord[] selectedRecords = userGrid.getSelectedRecords();

		List<TaskVO> taskVOList = new ArrayList<TaskVO>();

		for (ListGridRecord selectedRecord : selectedRecords) {
			TaskVO taskVO = RecordUtils.getTaskVO(selectedRecord);
			taskVOList.add(taskVO);
		}
		return taskVOList;
	}

	private class InfoHandler implements ClickHandler {

		@Override
		public void onClick(ClickEvent event) {
			InfoView infoView = new InfoView(SessionManager.getCurrentUserVO()
					.getUserName());
			infoView.draw();
		}

	}

	private class BackHandler implements ClickHandler {

		@Override
		public void onClick(ClickEvent event) {
			hide();

			AdminView adminView = new AdminView();
			adminView.draw();
		}
	}

	private class CreateHandler implements ClickHandler {

		@Override
		public void onClick(ClickEvent event) {
			TaskVO taskVO = new TaskVO();
			taskVO.setDailyPlanVO(dailyPlanVO);

			TaskView taskView = new TaskView(taskVO, DailyPlanView.this);
			taskView.draw();
		}
	}

	private class EditHandler implements ClickHandler {

		@Override
		public void onClick(ClickEvent event) {
			List<TaskVO> selectedTasks = getSelectedTasks();

			if (selectedTasks.size() == 0) {
				SC.say("Please select one task");
			} else if (selectedTasks.size() > 1) {
				SC.say("Please select only one task");
			} else {
				TaskVO taskVO = selectedTasks.get(0);
				taskVO.setDailyPlanVO(dailyPlanVO);

				TaskView taskView = new TaskView(taskVO, DailyPlanView.this);
				taskView.draw();
			}
		}
	}

	private class DeleteHandler implements ClickHandler {

		@Override
		public void onClick(ClickEvent event) {
			List<Integer> idList = getSelectedIds();
			taskService.delete(idList, new MyAsyncCallback<Void>() {

				@Override
				public void onSuccess(Void result) {
					showSuccessMessage("Task(s) successfuly deleted");
					loadDailyPlan();
				}
			});
		}
	}
}
